/* demo_main.c */

#include <stdio.h>

#include "board.h"
#include "sdcard_spi.h"

#define SDC_MUL_BLOCK_CNT  (2U)
static uint8_t gRxBuffer[SDC_BLOCK_SIZE_BYTE*SDC_MUL_BLOCK_CNT];
static uint8_t gTxBuffer[SDC_BLOCK_SIZE_BYTE*SDC_MUL_BLOCK_CNT];

static void MyAssert(bool bRet);
static bool DemoCardInstall(void);
static bool DemoCardInit(void);
static bool DemoCardSingleRW(void);
static bool DemoCardMultpleRW(void);

void exit_platform(void)
{
	while (1)
	{}
}

int main(void)
{
    board_init();

    /* print project logo. */
    printf("\r\n*----------------------------------------\r\n");
    printf("* Welcome to sdcard_spi demo project.\r\n");
    printf("* Compiled at %s on %s\r\n", __TIME__, __DATE__);
    printf("*----------------------------------------\r\n\r\n");

    printf("# DemoCardInstall() ...\r\n");
    MyAssert( DemoCardInstall() );

    printf("# DemoCardInit() ...\r\n");
    MyAssert( DemoCardInit() );
    
    printf("# DemoCardSingleRW() ...\r\n");
    MyAssert( DemoCardSingleRW() );

    printf("# DemoCardMultpleRW() ...\r\n");
    MyAssert( DemoCardMultpleRW() );

    printf("\r\n*----------------------------------------\r\n");
    printf("# End sdcard_spi demo project.\r\n");
    printf("*----------------------------------------\r\n");

    exit_platform();
    return 0U;
}

extern SDC_SPIHwDrv_T sdcard_spi_spi_hw_driver;

static bool DemoCardInstall(void)
{
    return SDC_Install(&sdcard_spi_spi_hw_driver);
}

static bool DemoCardInit(void)
{
    SDC_Info_T mSdcInfoStruct;
    bool bRet = false;

    printf("DemoCardInit() start ...\r\n");

    bRet = SDC_InitCard(&mSdcInfoStruct);
    if (bRet)
    {
        printf("CardType: ");
        switch (mSdcInfoStruct.CardType)
        {
            case eSDCCardTypeOfSDv2:
                printf("eSDCCardTypeOfSDv2");
                break;
            case eSDCCardTypeOfSDHC:
                printf("eSDCCardTypeOfSDHC");
                break;
            default:
                printf("eSDCCardUnknown");
                break;
        }
        printf("\r\n");
        printf("CardSize: %d MB\r\n",mSdcInfoStruct.CardBlkCnt/2U/1024U);
    }

    printf("DemoCardInit() end.\r\n");
    return bRet;
}

static bool DemoCardSingleRW(void)
{
    uint32_t blkIdx;
    uint8_t blkData;
    uint8_t tmp8;
    uint32_t i;

    printf("DemoCardSingleRW() start ...\r\n");

    do
    {
        /* Write. */
        printf("Input the writting block index: ");
        scanf("%d", &blkIdx);
        printf("\r\nInput the writting character: ");
        scanf("%c", &blkData);
        printf("\r\nWrite single block %d with data(ASCII) 0x%X\r\n", blkIdx, blkData);
        
        for (i = 0U; i < SDC_BLOCK_SIZE_BYTE; i++)
        {
            gTxBuffer[i] = blkData;
        }
        if ( !SDC_WriteBlock(blkIdx, gTxBuffer) )
        {
            printf("Write error.\r\n");
        }

        /* Read. */
        printf("Input the reading block index: ");
        scanf("%d", &blkIdx);
        printf("\r\nRead single block %d\r\n", blkIdx);
        if ( !SDC_ReadBlock(blkIdx, gRxBuffer) )
        {
            printf("Read error.\r\n");
        }
        else
        {
            /* printf reading data. */
            for (i = 0U; i < SDC_BLOCK_SIZE_BYTE; i++)
            {
                if (0U == i%8U)
                {
                    printf("\r\n%4d : ", i);
                }
                printf(" 0x%2X ", gRxBuffer[i]);
            }
            printf("\r\n");
        }

        /* Try again. */
        printf("Try again? [Y/N]: ");
        scanf("%c", &tmp8);
        printf("\r\n");
    } while (tmp8 == 'y' || tmp8 == 'Y');

    printf("DemoCardSingleRW() end.\r\n");

    return true;
}

static bool DemoCardMultpleRW(void)
{
    uint32_t blkIdx;
    uint8_t blkData;
    uint8_t tmp8;
    uint32_t i;

    printf("DemoCardMultpleRW() start ...\r\n");

    do
    {
        /* Write. */
        printf("Input the first writting block index: ");
        scanf("%d", &blkIdx);
        printf("\r\nInput the writting character: ");
        scanf("%c", &blkData);
        printf("\r\nWrite blocks %d-%d with data(ASCII) 0x%X\r\n", blkIdx, blkIdx+SDC_MUL_BLOCK_CNT-1U, blkData);
        
        for (i = 0U; i < SDC_BLOCK_SIZE_BYTE*SDC_MUL_BLOCK_CNT; i++)
        {
            gTxBuffer[i] = blkData;
        }
        if ( 0U != SDC_WriteBlocks(blkIdx, SDC_MUL_BLOCK_CNT, gTxBuffer) )
        {
            printf("Write error.\r\n");
        }

        /* Read. */
        printf("Input the first reading block index: ");
        scanf("%d", &blkIdx);
        printf("\r\nRead blocks %d-%d\r\n", blkIdx, blkIdx+SDC_MUL_BLOCK_CNT-1U);
        if ( 0U != SDC_ReadBlocks(blkIdx, SDC_MUL_BLOCK_CNT, gRxBuffer) )
        {
            printf("Read error.\r\n");
        }
        else
        {
            /* printf reading data. */
            for (i = 0U; i < SDC_BLOCK_SIZE_BYTE*SDC_MUL_BLOCK_CNT; i++)
            {
                if (0U == i%8U)
                {
                    printf("\r\n%4d : ", i);
                }
                printf(" 0x%2X ", gRxBuffer[i]);
            }
            printf("\r\n");
        }

        /* Try again. */
        printf("Try again? [Y/N]: ");
        scanf("%c", &tmp8);
        printf("\r\n");
    } while (tmp8 == 'y' || tmp8 == 'Y');

    printf("DemoCardMultpleRW() end.\r\n");

    return true;
}

static void MyAssert(bool bRet)
{
    if (bRet)
    {
        printf("# OK.\r\n");
    }
    else
    {
        printf("# Error.\r\n");
        exit_platform();
    }
}

/* EOF. */
